# -*- coding: utf-8 -*-

from PyQt5 import QtGui, QtCore
from PyQt5.Qt import *
from libs.RectItem import RectItem


class Scene(QGraphicsScene):
    '''subclass of QGraphicsScene'''

    # 自定义信号
    complete_rect = pyqtSignal()

    def __init__(self, w, h, pix):
        super().__init__()
        self.pix = pix
        self.pix_new = self.pix.scaled(w, h, Qt.KeepAspectRatio)

        self.setSceneRect(0, 0, self.pix_new.width(), self.pix_new.height())
        self.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.addPixmap(self.pix_new)

        # 初始化变量
        self.Flag = False  #标志是否标注
        self.tem_Rect = None
        self.Rect = None
        self.Rect_item = {}
        self.beginpoint = QPoint()
        self.endpoint = QPoint()
        self.count = 0

    def rect_generate_from_xml(self, picture_size, item_information):
        '''获取信息，计算出标注区域坐标，调用方法添加标注框'''
        new_w = self.pix_new.width()
        new_h = self.pix_new.height()
        origin_w = picture_size['width']
        origin_h = picture_size['height']
        ratio_w = new_w / origin_w #x_new / origin_x
        ratio_h = new_h / origin_h
        for dic in item_information:
            label = dic['name']
            xmin = int(dic['xmin'])
            ymin = int(dic['ymin'])
            xmax = int(dic['xmax'])
            ymax = int(dic['ymax'])
            begin = QPointF(xmin*ratio_w, ymin*ratio_w)
            end = QPointF(xmax*ratio_h, ymax*ratio_h)

            self.add_rect(begin,end)
            self.create_dic(label)

    def flage(self):
        '''使能标志位'''
        self.Flag = True

    def trans_zoom(self):
        '''使能图元的缩放移动'''
        for item in self.Rect_item:
            item.alter_label()


    def add_rect_temp(self, beginpoint, endpoint):
        '''添加矩形图元，这个函数负责的是鼠标拖动过程中的矩形绘制'''
        rect = QRectF(beginpoint, endpoint)
        self.tem_Rect = RectItem(rect=rect)
        self.addItem(self.tem_Rect)

    def add_rect(self, beginpoint, endpoint):
        '''添加矩形图元，鼠标拖动完成后的矩形，为了能够同时存在多个矩形，使用了字典存放RectItem'''
        rect = QRectF(beginpoint, endpoint)
        self.Rect = RectItem(rect=rect)
        self.addItem(self.Rect)

    def create_dic(self, label):
        '''创建字典 创建图元和标签的映射，并且添加数字元素用来唯一标识'''
        self.Rect_item[self.Rect] = [label, self.count]
        self.count += 1

    def create_rect(self, label):
        '''slot，dialog中的信号调用,调用添加图元和字典建立'''
        if self.Flag:
            if self.tem_Rect is not None:
                self.removeItem(self.tem_Rect)
                self.tem_Rect = None
            self.Flag = False
        self.add_rect(self.beginpoint, self.endpoint)
        self.create_dic(label)

    def disadd_rec(self):
        '''slot，dialog中的信号调用'''
        if self.Flag:
            if self.tem_Rect is not None:
                self.removeItem(self.tem_Rect)
                self.tem_Rect = None
            self.Flag = False

    def output(self):
        '''输出所有图元的信息'''
        label_list = []
        ratio_w = self.pix.width()/self.pix_new.width() #缩放后的图片相对于原图的缩放比例
        ratio_h = self.pix.height()/self.pix_new.height()
        for item, label in self.Rect_item.items():
            item_w = item.rect().width()
            item_h = item.rect().height()
            p = item.mapToScene(item.left_up) #左上角
            q = QPointF(p.x() + item_w, p.y() + item_h) #右下角
            xmin = int(p.x()*ratio_w)
            ymin = int(p.y()*ratio_h)
            xmax = int(q.x()*ratio_w)
            ymax = int(q.y()*ratio_h)
            bndbox = {"xmin":xmin,"ymin":ymin,"xmax":xmax,"ymax":ymax}
            dictionary = {'name':label[0],'pos':"Unspecified",'truncated':'0','difficult':'0','bndbox':bndbox}
            label_list.append(dictionary)
        return label_list

    def mousePressEvent(self, evt):
        if (Qt.LeftButton & evt.buttons()) & self.Flag:
            self.beginpoint = evt.scenePos()
            self.trans_zoom()
        item = self.itemAt(evt.scenePos(),QtGui.QTransform())
        self.clearSelection()
        print(item)
        if item is not None:
            item.setSelected(True)
        super().mousePressEvent(evt)

    def mouseMoveEvent(self, evt):
        super().mouseMoveEvent(evt)
        if (Qt.LeftButton & evt.buttons()) & self.Flag:
            self.endpoint = evt.scenePos()
            if self.tem_Rect is not None:
                self.removeItem(self.tem_Rect)
            self.add_rect_temp(self.beginpoint, self.endpoint)
    '''由于鼠标移动事件中会不断产生新坐标，因此需要不断的移除前一个矩形图元并添加新的矩形图元，从而避免画出无数个矩形图元的情况。'''

    def mouseReleaseEvent(self, evt):
        super().mouseReleaseEvent(evt)
        if self.Flag:
            self.trans_zoom()
        if self.tem_Rect is not None:
            self.complete_rect.emit()


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    view = QGraphicsView()
    # view.resize(500,500)
    pixmap = QPixmap('D:\\pythonProject\\QGrphicsView框架学习\\back.jpg')
    scene = Scene(500, 500, pixmap)
    view.setScene(scene)
    view.show()

    sys.exit(app.exec_())
